package com.pll.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName AMapGeocoderUtil
 * @Description 高德地图地址解析工具类
 * @Author 小鹿
 * @Date 2025/6/16 12:30
 */
@Slf4j
@Component
public class AMapGeocoderUtil {
    // 请替换为您自己的高德Key（控制台获取）
    private static final String KEY = "fb76db3ab9e55782539074c78c2f5ed7";
    private static final Pattern LOCATION_PATTERN =
            Pattern.compile("\"location\":\"?(\\d+\\.\\d+),(\\d+\\.\\d+)\"?");
    private static final Pattern FORMATTED_ADDRESS_PATTERN =
            Pattern.compile("\"formatted_address\":\"([^\"]+)\"");

    /**
     * 解析标准地址并返回包含详细信息的Map
     */
    public static Map<String, String> standardAddress(String fullAddress) {
        try {
            // 1. 验证地址格式
            if (!isStandardAddress(fullAddress)) {
                log.warn("地址格式不符合要求，必须包含省市区三级结构: {}", fullAddress);
                return null;
            }

            // 2. 解析地址成分
            String[] parts = parseAddressComponents(fullAddress);
            if (parts == null) return null;

            // 3. 构建请求URL
            String url = buildGeocodeUrl(parts[2], parts[1], parts[0]); // 参数顺序：详细地址、区、市

            // 4. 发送请求并解析
            String response = sendHttpGetRequest(url);
            return parseResponse(response);

        } catch (Exception e) {
            log.error("地理编码错误: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 兼容旧版本的方法，返回double[]类型
     */
    public static double[] standardAddressAsArray(String fullAddress) {
        Map<String, String> result = standardAddress(fullAddress);
        if (result != null && result.containsKey("longitude") && result.containsKey("latitude")) {
            return new double[]{
                    Double.parseDouble(result.get("longitude")),
                    Double.parseDouble(result.get("latitude"))
            };
        }
        return null;
    }

    /**
     * 解析API响应并提取所需信息
     */
    private static Map<String, String> parseResponse(String json) {
        Matcher locationMatcher = LOCATION_PATTERN.matcher(json);
        Matcher addressMatcher = FORMATTED_ADDRESS_PATTERN.matcher(json);

        Map<String, String> result = new HashMap<>();

        if (locationMatcher.find()) {
            result.put("longitude", locationMatcher.group(1));
            result.put("latitude", locationMatcher.group(2));
            result.put("location", locationMatcher.group(1) + "," + locationMatcher.group(2));
        } else {
            log.warn("未找到经纬度，响应内容: {}", json);
            return null;
        }

        if (addressMatcher.find()) {
            result.put("formattedAddress", addressMatcher.group(1));
        } else {
            // 如果没有找到格式化地址，使用原始地址
            result.put("formattedAddress", "未知地址");
        }

        return result;
    }

    /**
     * 验证是否为标准地址格式（包含省市区）
     */
    private static boolean isStandardAddress(String address) {
        return address != null &&
                (address.matches(".*省.*市.*区.*") ||
                        address.matches(".*市.*区.*")); // 兼容直辖市
    }

    /**
     * 解析地址成分 [0]市 [1]区 [2]详细地址
     */
    private static String[] parseAddressComponents(String fullAddress) {
        // 处理直辖市（北京、上海、天津、重庆）
        if (fullAddress.matches("(北京|上海|天津|重庆)市.*区.*")) {
            String city = fullAddress.substring(0, 2); // 提取"北京市"
            String remaining = fullAddress.substring(2);

            Matcher m = Pattern.compile("(.*?区)(.*)").matcher(remaining);
            if (m.find()) {
                return new String[]{city, m.group(1), m.group(2)};
            }
        }
        // 处理省级地址
        else if (fullAddress.matches(".*省.*市.*区.*")) {
            Matcher m = Pattern.compile("(.*?省)(.*?市)(.*?区)(.*)").matcher(fullAddress);
            if (m.find()) {
                return new String[]{m.group(2), m.group(3), m.group(4)}; // 市、区、详细地址
            }
        }

        log.warn("无法解析地址成分: {}", fullAddress);
        return null;
    }

    /**
     * 构造地理编码请求URL
     */
    private static String buildGeocodeUrl(String detail, String district, String city)
            throws UnsupportedEncodingException
    {
        return String.format(
                "https://restapi.amap.com/v3/geocode/geo?address=%s&key=%s&city=%s&district=%s",
                URLEncoder.encode(detail, "UTF-8"),
                KEY,
                URLEncoder.encode(city, "UTF-8"),
                URLEncoder.encode(district, "UTF-8")
        );
    }

    /**
     * 发送HTTP GET请求
     */
    private static String sendHttpGetRequest(String url) throws Exception {
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(5000);
        conn.setReadTimeout(5000);

        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(conn.getInputStream(), "UTF-8"))) {
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                response.append(line);
            }
            return response.toString();
        }
    }
}